﻿using System.Text;
using Aurora.TaskScheduler.Dashboard;
using Gateway.UI.Api.Filters.Attributes;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;

namespace Gateway.UI.Api.Filters
{
    /// <summary>
    /// 结果过滤器
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
    public class ResultFilter : Attribute, IResultFilter
    {
        private readonly ILogger<ResultFilter> _logger;
        private readonly DashboardOptions _dashboardOptions;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="dashboardOptions"></param>
        public ResultFilter(ILogger<ResultFilter> logger, IOptions<DashboardOptions> dashboardOptions)
        {
            _logger = logger;
            _dashboardOptions = dashboardOptions.Value;
        }

        /// <summary>
        /// 执行完成
        /// </summary>
        /// <param name="context"></param>
        public async void OnResultExecuted(ResultExecutedContext context)
        {
            if (SkipByPath(context.HttpContext))
                return;
            var skipLoggerAttribute = (SkipLoggerAttribute)context.ActionDescriptor.FilterDescriptors
                .FirstOrDefault(p => p.Filter is SkipLoggerAttribute)?.Filter;
            if (skipLoggerAttribute == null)
            {
                context.HttpContext.Request.EnableBuffering();
                var requestInfo = await ReadRequest(context.HttpContext);
                _logger.LogInformation("[请求日志]：" + requestInfo);
            }

            try
            {
                string responseInfo = context.Result != null ? JsonConvert.SerializeObject(context.Result) : "";
                _logger.LogInformation("[响应日志]：" + responseInfo);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        /// <summary>
        /// 即将执行
        /// </summary>
        /// <param name="context"></param>
        public void OnResultExecuting(ResultExecutingContext context)
        {
            context.HttpContext.Request.EnableBuffering();

            #region 数据格式处理

            if (context.Result is BadRequestObjectResult jsonResult)
            {
                //不做处理
            }
            else
            {
                if (context.Result is ObjectResult objectResult)
                {
                    context.Result = new ObjectResult(new ApiResult<object>()
                    {
                        Code = objectResult.StatusCode ?? 200,
                        Data = objectResult.Value,
                        Success = true
                    });
                }
                else if (context.Result is ContentResult contentResult)
                {
                    context.Result = new ObjectResult(
                        new ApiResult<object>()
                        {
                            Code = contentResult.StatusCode ?? 200,
                            Message = "",
                            Data = contentResult.Content,
                            Success = true
                        });
                }
                else if (context.Result is StatusCodeResult statusCodeResult)
                {
                    context.Result = new ObjectResult(
                        new ApiResult()
                        {
                            Code = statusCodeResult.StatusCode,
                            Message = ""
                        });
                }
            }

            #endregion
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private async Task<string> ReadRequest(HttpContext context)
        {
            var request = context.Request;
            var url = request.GetEncodedUrl();
            var message = $"[请求地址]:{url}";
            if (!(request.ContentLength > 0)) return message;

            request.Body.Position = 0;
            var buffer = new byte[Convert.ToInt32(request.ContentLength)];
            await request.Body.ReadAsync(buffer, 0, buffer.Length);
            var bodyAsText = Encoding.UTF8.GetString(buffer).Replace("\r\n", "\n").Replace("\n", "");

            message += $@";[请求参数]:{bodyAsText}";
            return message;
        }


        private bool SkipByPath(HttpContext context)
        {
            //if (context.Request.Path.StartsWithSegments(_dashboardOptions.PathBase))
            //{
            //    return true;
            //}

            //return false;
            return false;
        }
    }
}